import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;

/**
 * This class contains all methods to build and
 * return (not sending though) a valid HTTP response
 * upon a HTTP request.
 *
 * @author Marlon Etheredge
 * @author <a href="mailto:m.etheredge@gmail.com">m.etheredge@gmail.com</a>
 * @author <a href="http://www.foxage.nl/">http://www.foxage.nl</a>
 */
public class HttpResponse {
	
	/** String Array containing all method parameters. */
	private String[] methodParameters;
	
	/** Describes wich HTTP method is requested. */
	private HttpMethod httpMethod;
	
	/** HttpHeader for this HttpResponse. */
	private HttpHeader httpHeader;
	
	/** Constructs a new empty HttpResponse. */
	public HttpResponse() {
	    this.httpHeader = new HttpHeader();
	}
	
	/** 
	 * Constructs a new HttpResponse with parameters.
	 *
	 * @param contentType ContentType of this HttpResponse
	 * @param methodParameters MethodParameters of this HttpResponse
	 * @param httpMethod HttpMethod of this HttpResponse
	 */
	public HttpResponse(String[] methodParameters, HttpMethod httpMethod) {
		this.httpHeader = new HttpHeader();
		this.methodParameters = methodParameters;
		this.httpMethod = httpMethod;
	}
	
	/** 
	 * Sets the httpMethod.
	 *
	 * @param httpMethod HttpMethod to be set
	 */
	public void setHttpMethod(HttpMethod httpMethod) {
		this.httpMethod = httpMethod;
	}
	
	/** 
	 * Returns Close Connection flag.
	 *
	 * @return Flag telling wether the connection should be closed
	 */
	public boolean getCloseConnection() {
		return this.httpHeader.getHttpConnectionCloseFlag();
	}
	
	/** 
	 * Sets the methodParameters.
	 *
	 * @param methodParameters MethodParameters to be set
	 */
	public void setMethodParameters(String[] methodParameters) {
		this.methodParameters = methodParameters;
	}
	
	/** 
	 * Builds and returns the HttpResponse.
	 *
	 * @return byte[] Byte[] containing the built HttpRespone
	 */
	@SuppressWarnings("unchecked")
	public byte[] build() {
		String body = "";
		String statusline = "";
		byte[] headerBytes = new byte[0];
		byte[] fileBytes = new byte[0];
		byte[] responseBytes = new byte[0];
		
		switch(this.httpMethod) {
			case GET:
				try {
					FileHandler fileHandler = new FileHandler(this.methodParameters[0]);
					fileBytes = fileHandler.readFile();
					
					this.httpHeader.setStatusLine(" 200 OK");
					this.httpHeader.setHttpContentLength(fileBytes.length);
					this.httpHeader.setHttpContentType(fileHandler.getMimeType());
					this.httpHeader.setLastModified(fileHandler.getLastModifiedDate());
					
					headerBytes = this.httpHeader.build();
				} catch(FileNotFoundException exception) {
					fileBytes = new String("<h1>404 - Page not found.</h1>").getBytes();
					
					httpHeader.setStatusLine(" 404 Not Found");
					headerBytes = this.httpHeader.build();
				} catch(IOException exception) {
					fileBytes = new String("<h1>500 - Internal Server Error.</h1>").getBytes();
					
					httpHeader.setStatusLine(" 500 Internal Server Error");
					headerBytes = this.httpHeader.build();
				}
				
				break;
			case POST:
				//Unimplemented
				
				break;
			case HEAD:
				try {
					FileHandler fileHandler = new FileHandler(this.methodParameters[0]);
					fileBytes = fileHandler.readFile();
					
					this.httpHeader.setStatusLine(" 200 OK");
					this.httpHeader.setHttpContentLength(fileBytes.length);
					this.httpHeader.setHttpContentType(fileHandler.getMimeType());
					this.httpHeader.setLastModified(fileHandler.getLastModifiedDate());
					
					headerBytes = this.httpHeader.build();
				} catch(FileNotFoundException exception) {
					fileBytes = new String("<h1>404 - Page not found.</h1>").getBytes();
					
					httpHeader.setStatusLine(" 404 Not Found");
					headerBytes = this.httpHeader.build();
				} catch(IOException exception) {
					fileBytes = new String("<h1>500 - Internal Server Error.</h1>").getBytes();
					
					httpHeader.setStatusLine(" 500 Internal Server Error");
					headerBytes = this.httpHeader.build();
				}
				break;
			case CONNECT:
				//Unimplemented

				break;
			case PUT:
				//Unimplemented

				break;
			case DELETE:
				//Unimplemented

				break;
			case TRACE:
				//Unimplemented

				break;
			case OPTIONS:
				//Unimplemented

				break;
		}
		
		responseBytes = new byte[headerBytes.length + fileBytes.length];
		
		System.arraycopy(headerBytes, 0, responseBytes, 0, headerBytes.length);
		
        if(this.httpMethod == HttpMethod.GET)
			System.arraycopy(fileBytes, 0, responseBytes, headerBytes.length, fileBytes.length);
		
		return responseBytes;
	}
	
}
